home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / cg_effects.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  9.1 KB  |  377 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. // cg_effects.c -- these functions generate localentities, usually as a result
  4. // of event processing
  5.  
  6. #include "cg_local.h"
  7.  
  8.  
  9. /*
  10. ==================
  11. CG_BubbleTrail
  12.  
  13. Bullets shot underwater
  14. ==================
  15. */
  16. void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
  17.     vec3_t        move;
  18.     vec3_t        vec;
  19.     float        len;
  20.     int            i;
  21.  
  22.     VectorCopy (start, move);
  23.     VectorSubtract (end, start, vec);
  24.     len = VectorNormalize (vec);
  25.  
  26.     // advance a random amount first
  27.     i = rand() % (int)spacing;
  28.     VectorMA( move, i, vec, move );
  29.  
  30.     VectorScale (vec, spacing, vec);
  31.  
  32.     for ( ; i < len; i += spacing ) {
  33.         localEntity_t    *le;
  34.         refEntity_t        *re;
  35.  
  36.         le = CG_AllocLocalEntity();
  37.         le->leFlags = LEF_PUFF_DONT_SCALE;
  38.         le->leType = LE_MOVE_SCALE_FADE;
  39.         le->startTime = cg.time;
  40.         le->endTime = cg.time + 1000 + random() * 250;
  41.         le->lifeRate = 1.0 / ( le->endTime - le->startTime );
  42.  
  43.         re = &le->refEntity;
  44.         re->shaderTime = cg.time / 1000.0f;
  45.  
  46.         re->reType = RT_SPRITE;
  47.         re->rotation = 0;
  48.         re->radius = 3;
  49.         re->customShader = cgs.media.waterBubbleShader;
  50.         re->shaderRGBA[0] = 0xff;
  51.         re->shaderRGBA[1] = 0xff;
  52.         re->shaderRGBA[2] = 0xff;
  53.         re->shaderRGBA[3] = 0xff;
  54.  
  55.         le->color[3] = 1.0;
  56.  
  57.         le->pos.trType = TR_LINEAR;
  58.         le->pos.trTime = cg.time;
  59.         VectorCopy( move, le->pos.trBase );
  60.         le->pos.trDelta[0] = crandom()*5;
  61.         le->pos.trDelta[1] = crandom()*5;
  62.         le->pos.trDelta[2] = crandom()*5 + 6;
  63.  
  64.         VectorAdd (move, vec, move);
  65.     }
  66. }
  67.  
  68. /*
  69. =====================
  70. CG_SmokePuff
  71.  
  72. Adds a smoke puff or blood trail localEntity.
  73. =====================
  74. */
  75. localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel, 
  76.                    float radius,
  77.                    float r, float g, float b, float a,
  78.                    float duration,
  79.                    int startTime,
  80.                    int leFlags,
  81.                    qhandle_t hShader ) {
  82.     static int    seed = 0x92;
  83.     localEntity_t    *le;
  84.     refEntity_t        *re;
  85.  
  86.     le = CG_AllocLocalEntity();
  87.     le->leFlags = leFlags;
  88.     le->radius = radius;
  89.  
  90.     re = &le->refEntity;
  91.     re->rotation = Q_random( &seed ) * 360;
  92.     re->radius = radius;
  93.     re->shaderTime = startTime / 1000.0f;
  94.  
  95.     le->leType = LE_MOVE_SCALE_FADE;
  96.     le->startTime = startTime;
  97.     le->endTime = startTime + duration;
  98.     le->lifeRate = 1.0 / ( le->endTime - le->startTime );
  99.     le->color[0] = r;
  100.     le->color[1] = g; 
  101.     le->color[2] = b;
  102.     le->color[3] = a;
  103.  
  104.  
  105.     le->pos.trType = TR_LINEAR;
  106.     le->pos.trTime = startTime;
  107.     VectorCopy( vel, le->pos.trDelta );
  108.     VectorCopy( p, le->pos.trBase );
  109.  
  110.     VectorCopy( p, re->origin );
  111.     re->customShader = hShader;
  112.  
  113.     // rage pro can't alpha fade, so use a different shader
  114.     if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
  115.         re->customShader = cgs.media.smokePuffRageProShader;
  116.         re->shaderRGBA[0] = 0xff;
  117.         re->shaderRGBA[1] = 0xff;
  118.         re->shaderRGBA[2] = 0xff;
  119.         re->shaderRGBA[3] = 0xff;
  120.     } else {
  121.         re->shaderRGBA[0] = le->color[0] * 0xff;
  122.         re->shaderRGBA[1] = le->color[1] * 0xff;
  123.         re->shaderRGBA[2] = le->color[2] * 0xff;
  124.         re->shaderRGBA[3] = 0xff;
  125.     }
  126.  
  127.     re->reType = RT_SPRITE;
  128.     re->radius = le->radius;
  129.  
  130.     return le;
  131. }
  132.  
  133. /*
  134. ==================
  135. CG_SpawnEffect
  136.  
  137. Player teleporting in or out
  138. ==================
  139. */
  140. void CG_SpawnEffect( vec3_t org ) {
  141.     localEntity_t    *le;
  142.     refEntity_t        *re;
  143.  
  144.     le = CG_AllocLocalEntity();
  145.     le->leFlags = 0;
  146.     le->leType = LE_FADE_RGB;
  147.     le->startTime = cg.time;
  148.     le->endTime = cg.time + 500;
  149.     le->lifeRate = 1.0 / ( le->endTime - le->startTime );
  150.  
  151.     le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
  152.  
  153.     re = &le->refEntity;
  154.  
  155.     re->reType = RT_MODEL;
  156.     re->shaderTime = cg.time / 1000.0f;
  157.  
  158.     re->customShader = cgs.media.teleportEffectShader;
  159.     re->hModel = cgs.media.teleportEffectModel;
  160.     AxisClear( re->axis );
  161.  
  162.     VectorCopy( org, re->origin );
  163.     re->origin[2] -= 24;
  164. }
  165.  
  166.  
  167.  
  168.  
  169. /*
  170. ====================
  171. CG_MakeExplosion
  172. ====================
  173. */
  174. localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir, 
  175.                                 qhandle_t hModel, qhandle_t shader,
  176.                                 int msec, qboolean isSprite ) {
  177.     float            ang;
  178.     localEntity_t    *ex;
  179.     int                offset;
  180.     vec3_t            tmpVec, newOrigin;
  181.  
  182.     if ( msec <= 0 ) {
  183.         CG_Error( "CG_MakeExplosion: msec = %i", msec );
  184.     }
  185.  
  186.     // skew the time a bit so they aren't all in sync
  187.     offset = rand() & 63;
  188.  
  189.     ex = CG_AllocLocalEntity();
  190.     if ( isSprite ) {
  191.         ex->leType = LE_SPRITE_EXPLOSION;
  192.  
  193.         // randomly rotate sprite orientation
  194.         ex->refEntity.rotation = rand() % 360;
  195.         VectorScale( dir, 16, tmpVec );
  196.         VectorAdd( tmpVec, origin, newOrigin );
  197.     } else {
  198.         ex->leType = LE_EXPLOSION;
  199.         VectorCopy( origin, newOrigin );
  200.  
  201.         // set axis with random rotate
  202.         if ( !dir ) {
  203.             AxisClear( ex->refEntity.axis );
  204.         } else {
  205.             ang = rand() % 360;
  206.             VectorCopy( dir, ex->refEntity.axis[0] );
  207.             RotateAroundDirection( ex->refEntity.axis, ang );
  208.         }
  209.     }
  210.  
  211.     ex->startTime = cg.time - offset;
  212.     ex->endTime = ex->startTime + msec;
  213.  
  214.     // bias the time so all shader effects start correctly
  215.     ex->refEntity.shaderTime = ex->startTime / 1000.0f;
  216.  
  217.     ex->refEntity.hModel = hModel;
  218.     ex->refEntity.customShader = shader;
  219.  
  220.     // set origin
  221.     VectorCopy( newOrigin, ex->refEntity.origin );
  222.     VectorCopy( newOrigin, ex->refEntity.oldorigin );
  223.  
  224.     ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
  225.  
  226.     return ex;
  227. }
  228.  
  229.  
  230. /*
  231. =================
  232. CG_Bleed
  233.  
  234. This is the spurt of blood when a character gets hit
  235. =================
  236. */
  237. void CG_Bleed( vec3_t origin, int entityNum ) {
  238.     localEntity_t    *ex;
  239.  
  240.     if ( !cg_blood.integer ) {
  241.         return;
  242.     }
  243.  
  244.     ex = CG_AllocLocalEntity();
  245.     ex->leType = LE_EXPLOSION;
  246.  
  247.     ex->startTime = cg.time;
  248.     ex->endTime = ex->startTime + 500;
  249.     
  250.     VectorCopy ( origin, ex->refEntity.origin);
  251.     ex->refEntity.reType = RT_SPRITE;
  252.     ex->refEntity.rotation = rand() % 360;
  253.     ex->refEntity.radius = 16;
  254.  
  255.     ex->refEntity.customShader = cgs.media.bloodExplosionShader;
  256.  
  257.     // don't show player's own blood in view
  258.     if ( entityNum == cg.snap->ps.clientNum ) {
  259.         ex->refEntity.renderfx |= RF_THIRD_PERSON;
  260.     }
  261. }
  262.  
  263.  
  264.  
  265. /*
  266. ==================
  267. CG_LaunchGib
  268. ==================
  269. */
  270. void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
  271.     localEntity_t    *le;
  272.     refEntity_t        *re;
  273.  
  274.     le = CG_AllocLocalEntity();
  275.     re = &le->refEntity;
  276.  
  277.     le->leType = LE_FRAGMENT;
  278.     le->startTime = cg.time;
  279.     le->endTime = le->startTime + 5000 + random() * 3000;
  280.  
  281.     VectorCopy( origin, re->origin );
  282.     AxisCopy( axisDefault, re->axis );
  283.     re->hModel = hModel;
  284.  
  285.     le->pos.trType = TR_GRAVITY;
  286.     VectorCopy( origin, le->pos.trBase );
  287.     VectorCopy( velocity, le->pos.trDelta );
  288.     le->pos.trTime = cg.time;
  289.  
  290.     le->bounceFactor = 0.3;
  291.  
  292.     le->leBounceSoundType = LEBS_BLOOD;
  293.     le->leMarkType = LEMT_BLOOD;
  294. }
  295.  
  296. /*
  297. ===================
  298. CG_GibPlayer
  299.  
  300. Generated a bunch of gibs launching out from the bodies location
  301. ===================
  302. */
  303. #define    GIB_VELOCITY    250
  304. #define    GIB_JUMP        250
  305. void CG_GibPlayer( vec3_t playerOrigin ) {
  306.     vec3_t    origin, velocity;
  307.  
  308.     if ( !cg_blood.integer ) {
  309.         return;
  310.     }
  311.  
  312.     VectorCopy( playerOrigin, origin );
  313.     velocity[0] = crandom()*GIB_VELOCITY;
  314.     velocity[1] = crandom()*GIB_VELOCITY;
  315.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  316.     if ( rand() & 1 ) {
  317.         CG_LaunchGib( origin, velocity, cgs.media.gibSkull );
  318.     } else {
  319.         CG_LaunchGib( origin, velocity, cgs.media.gibBrain );
  320.     }
  321.  
  322.     // allow gibs to be turned off for speed
  323.     if ( !cg_gibs.integer ) {
  324.         return;
  325.     }
  326.  
  327.     VectorCopy( playerOrigin, origin );
  328.     velocity[0] = crandom()*GIB_VELOCITY;
  329.     velocity[1] = crandom()*GIB_VELOCITY;
  330.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  331.     CG_LaunchGib( origin, velocity, cgs.media.gibAbdomen );
  332.  
  333.     VectorCopy( playerOrigin, origin );
  334.     velocity[0] = crandom()*GIB_VELOCITY;
  335.     velocity[1] = crandom()*GIB_VELOCITY;
  336.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  337.     CG_LaunchGib( origin, velocity, cgs.media.gibArm );
  338.  
  339.     VectorCopy( playerOrigin, origin );
  340.     velocity[0] = crandom()*GIB_VELOCITY;
  341.     velocity[1] = crandom()*GIB_VELOCITY;
  342.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  343.     CG_LaunchGib( origin, velocity, cgs.media.gibChest );
  344.  
  345.     VectorCopy( playerOrigin, origin );
  346.     velocity[0] = crandom()*GIB_VELOCITY;
  347.     velocity[1] = crandom()*GIB_VELOCITY;
  348.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  349.     CG_LaunchGib( origin, velocity, cgs.media.gibFist );
  350.  
  351.     VectorCopy( playerOrigin, origin );
  352.     velocity[0] = crandom()*GIB_VELOCITY;
  353.     velocity[1] = crandom()*GIB_VELOCITY;
  354.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  355.     CG_LaunchGib( origin, velocity, cgs.media.gibFoot );
  356.  
  357.     VectorCopy( playerOrigin, origin );
  358.     velocity[0] = crandom()*GIB_VELOCITY;
  359.     velocity[1] = crandom()*GIB_VELOCITY;
  360.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  361.     CG_LaunchGib( origin, velocity, cgs.media.gibForearm );
  362.  
  363.     VectorCopy( playerOrigin, origin );
  364.     velocity[0] = crandom()*GIB_VELOCITY;
  365.     velocity[1] = crandom()*GIB_VELOCITY;
  366.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  367.     CG_LaunchGib( origin, velocity, cgs.media.gibIntestine );
  368.  
  369.     VectorCopy( playerOrigin, origin );
  370.     velocity[0] = crandom()*GIB_VELOCITY;
  371.     velocity[1] = crandom()*GIB_VELOCITY;
  372.     velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
  373.     CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
  374.  
  375. }
  376.  
  377.